package com.pwt.service;

import com.pwt.common.CustomException;
import com.pwt.common.DataNotFoundException;
import com.pwt.common.ResultCode;
import com.pwt.entity.Menu;
import com.pwt.model.MenuTreeModel;
import com.pwt.repository.MenuRepository;
import com.pwt.repository.RoleMenuRepository;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Menu service层
 *
 * @author auto generated
 * @date 2021-08-30 11:15:30
 */
@Service
public class MenuService {
    @Autowired
    MenuRepository menuRepository;

    @Autowired
    RoleMenuRepository roleMenuRepository;

    @CacheEvict(value = "menu_tree",allEntries = true)
    public Menu add(Menu menu) throws CustomException {
        String parentId = menu.getParentId();
        if(StringUtils.isNotBlank(parentId)) {
            int count  = menuRepository.countById(parentId);
            if(count == 0) {
                throw new CustomException(ResultCode.PARENT_MENU_NOT_FOUND);
            }
        }
        return menuRepository.save(menu);
    }

    /**
     * 权限树
     * @return
     */
    //@Cacheable(value = "menu_tree")
    public MenuTreeModel tree() {
        MenuTreeModel abstractModel = new MenuTreeModel();
        abstractModel.setName("虚拟节点");
        List<Menu> menus = menuRepository.findAll(Sort.by(Sort.Order.asc("sortNumber")));
        List<Menu> first = menus.stream().filter(menu -> menu.getLevel() == 0).collect(Collectors.toList());
        List<Menu> second = menus.stream().filter(menu -> menu.getLevel() == 1).collect(Collectors.toList());
        List<Menu> third = menus.stream().filter(menu -> menu.getLevel() == 2).collect(Collectors.toList());
        List<MenuTreeModel> firstMenu = new ArrayList<>();
        for(Menu menu:first) {
            firstMenu.add(new MenuTreeModel(menu));
        }
        abstractModel.setChildren(firstMenu);
        for(MenuTreeModel model:firstMenu) {
            List<MenuTreeModel> secondMenu = new ArrayList<>();
            for(Menu menu : second) {
                if(model.getId().equals(menu.getParentId())) {
                    secondMenu.add(new MenuTreeModel(menu));
                }
            }
            model.setChildren(secondMenu);
            for(MenuTreeModel sModel:secondMenu) {
                List<MenuTreeModel> thirdMenu = new ArrayList<>();
                for(Menu menu : third) {
                    if(sModel.getId().equals(menu.getParentId())) {
                        thirdMenu.add(new MenuTreeModel(menu));
                    }
                }
                sModel.setChildren(thirdMenu);
            }
        }
        return abstractModel;
    }

    public Menu edit(Menu menu) throws CustomException {
        String parentId = menu.getParentId();
        if(StringUtils.isNotBlank(parentId)) {
            int count  = menuRepository.countById(parentId);
            if(count == 0) {
                throw new CustomException(ResultCode.PARENT_MENU_NOT_FOUND);
            }
        }
        return menuRepository.save(menu);
    }

    @Transactional(rollbackFor = Exception.class)
    public String delete(String id) throws CustomException {
        int count = menuRepository.countByParentId(id);
        if(count > 0) {
            throw new CustomException(ResultCode.MENU_HAS_CHILDREN);
        }
        roleMenuRepository.deleteByMenuId(id);
        menuRepository.deleteById(id);
        return id;
    }
}
